#ifndef ZL_BASIC
#define ZL_BASIC

#include <cassert>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#else
#include <x86intrin.h>
#include <stdint.h>
#include <stddef.h>
#endif

namespace zl
{
#ifdef           _MSC_VER
#ifdef           ZL_64
	typedef  __int64         zint;
	typedef signed __int64			zsint;
	typedef unsigned __int64		zuint;
#else
	typedef  __int32                zint;
	typedef  signed  __int32        zsint;
	typedef  unsigned __int32       zuint;
#endif
	typedef signed __int8			zint8_t;
	typedef unsigned __int8			zuint8_t;
	typedef signed __int16			zint16_t;
	typedef unsigned __int16		zuint16_t;
	typedef signed __int32			zint32_t;
	typedef unsigned __int32		zuint32_t;
	typedef signed __int64			zint64_t;
	typedef unsigned __int64		zuint64_t;
	typedef  signed __int64         pos_t;
#else
#ifdef            ZL_64
	typedef  int64_t           zint;
	typedef  signed int64_t    zsint;
	typedef  uint64_t          zuint;
#else
	typedef  int               zint;
	typedef  signed int        zsint;
	typedef  unsigned  int     zuint;
#endif
	typedef  long long        pos_t;
	typedef int8_t			  zint8_t;
	typedef uint8_t			  zuint8_t;
	typedef int16_t			  zint16_t;
	typedef uint16_t		  zuint16_t;
	typedef int32_t			  zint32_t;
	typedef uint32_t		  zuint32_t;
	typedef int64_t			  zint64_t;
	typedef uint64_t		  zuint64_t;
#endif
	
	class Object
	{
	public:
		virtual ~Object();
	};

	class NotCopyable
	{
	public:
		NotCopyable();
	private:
		NotCopyable(const NotCopyable&);
		NotCopyable& operator =(const NotCopyable&);
	};

	class Interface :private NotCopyable
	{
	public:
		virtual ~Interface();
	};

	template<typename T>
	struct KeyType
	{
	public:
		typedef T Type;

		static T GetKeyValue(const T& value)
		{
			return value;
		}
	};

	struct DateTime
	{
		zint				year;
		zint				month;
		zint				dayOfWeek;
		zint				day;
		zint				hour;
		zint				minute;
		zint				second;
		zint				milliseconds;

		zuint64_t			totalMilliseconds;
		zuint64_t			filetime;

		static DateTime		LocalTime();
		static DateTime		UtcTime();
		static DateTime		FromDateTime(zint _year, zint _month, zint _day, zint _hour = 0, zint _minute = 0, zint _second = 0, zint _milliseconds = 0);
		static DateTime		FromFileTime(zuint64_t filetime);

		DateTime();

		DateTime			ToLocalTime();
		DateTime			ToUtcTime();
		DateTime			Forward(zuint64_t milliseconds);
		DateTime			Backward(zuint64_t milliseconds);

		bool operator==(const DateTime& value)const { return filetime == value.filetime; }
		bool operator!=(const DateTime& value)const { return filetime != value.filetime; }
		bool operator<(const DateTime& value)const { return filetime<value.filetime; }
		bool operator<=(const DateTime& value)const { return filetime <= value.filetime; }
		bool operator>(const DateTime& value)const { return filetime>value.filetime; }
		bool operator>=(const DateTime& value)const { return filetime >= value.filetime; }
	};
};
#endif